﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework;
using System.Reflection;
using Microsoft.Xna.Framework.Graphics;
using System.IO;

namespace Pavilion
{
    static public class GameEngine
    {
        static private Game Game { get; set; }
        static public GameWindow Window { get { return Game.Window; } }
        static public int WindowWidth { get { return Window.ClientBounds.Width; } }
        static public int WindowHeight { get { return Window.ClientBounds.Height; } }

        static public void Initialize(Game game, IServiceProvider services, GraphicsDevice graphics, string contentDirectory)
        {
            Game = game;
            ContentDirectory = contentDirectory;

            GameServiceContainer serviceContainer = new GameServiceContainer();
            ResourceManager.Instance.Initialize(services);
            DrawManager.Instance.Initialize(graphics);
        }

        static public T CreateInstance<T>(string assemblyName, string name)
        {
            string assemblyNameWithoutExt = assemblyName.Substring(0, assemblyName.LastIndexOf(".") + 1);
            Assembly assembly = Assembly.LoadFile(Environment.CurrentDirectory + @"\" + assemblyName);
            T instance = (T)Activator.CreateInstance(assembly.GetType(assemblyNameWithoutExt + name));
            
            return instance;
        }

        static public IEnumerable<Type> ObtainAllTypes<T>(string assemblyName)
        {
            Assembly assembly = Assembly.LoadFile(Environment.CurrentDirectory + @"\" + assemblyName);

            List<Type> collection = new List<Type>();

            foreach (Type type in assembly.GetTypes())
            {
                if (typeof(T).IsAssignableFrom(type))
                    collection.Add(type);
            }

            return collection;

            // return assembly.GetTypes().Where(typeof(T).IsAssignableFrom(type)).ToArray();
        }

        static public IEnumerable<string> GetGameSessions()
        {
            return GetDirectoryNames(GameEngine.GameSessionsDirectory);
        }

        static public IEnumerable<string> GetResourceItemList()
        {
            return GetDirectoryNames(GameEngine.AnimationsDirectory);
        }

        static public IEnumerable<string> GetAnimations(string characterName)
        {
            return GetDirectoryNames(GameEngine.AnimationsDirectory + characterName + @"\Built Data");
        }

        static public IEnumerable<string> GetGameItems(string gameSessionName)
        {
            return GetFileNames(GameEngine.GameSessionsDirectory + gameSessionName + @"\GameItems\", ".xml");
        }

        static public IEnumerable<string> GetFileNames(string path, string extension)
        {
            string[] filePathList = Directory.GetFiles(path);

            foreach (string filePath in filePathList)
            {
                int firstIndex = filePath.LastIndexOf(@"\") + 1;
                int nameLenght = filePath.LastIndexOf(extension) - firstIndex;
                yield return filePath.Substring(firstIndex, nameLenght);
            }
        }

        static public IEnumerable<string> GetDirectoryNames(string path)
        {
            string[] directoryPathList = Directory.GetDirectories(path);

            foreach (string directoryPath in directoryPathList)
                yield return directoryPath.Substring(directoryPath.LastIndexOf(@"\") + 1);
        }

        static public T EnumParse<T>(string value)
        {
            return (T)Enum.Parse(typeof(T), value);
        }

        /// <summary>
        /// Gets the Content Directory of this Game.
        /// </summary>
        static public string ContentDirectory { get; set; }

        /// <summary>
        /// Gets teh Game Sessions Directory of this game.
        /// ContentDirectory + @"GameSessions\";
        /// </summary>
        static public string GameSessionsDirectory
        {
            get { return ContentDirectory + @"GameSessions\"; }
        }

        /// <summary>
        /// Gets the resource path of where all the content resides.
        /// ContentDirectory + @"GameResources\";
        /// </summary>
        static public string GameResourcesDirectory
        {
            get { return ContentDirectory + @"GameResources\"; }
        }

        /// <summary>
        /// Gets the resource path of where all the content resides.
        /// ContentDirectory + @"GameResources\Animations\";
        /// </summary>
        static public string AnimationsDirectory
        {
            get { return ContentDirectory + @"GameResources\Animations\"; }
        }

        static public string NodeLayoutDirectory
        {
            get { return ContentDirectory + @"LayoutResources\Animations\"; }
        }
    }
}
